home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_08 / phillip2 / cips6.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-24  |  73.7 KB  |  2,741 lines

  1.  
  2.    /*************************** 
  3.    * 
  4.    *   cips6.c 
  5.    *   COMPOSITE FILE COMPRISING: 
  6.    *   filter.c 
  7.    *   display.c 
  8.    *   djet.c 
  9.    *   scale.c 
  10.    * 
  11.    ***************************\ 
  12.  
  13.  
  14.  
  15.     /***********************************************
  16.     *
  17.     *    file d:\cips\filter.c
  18.     *
  19.     *    Functions: This file contains
  20.     *       filter_image
  21.     *       median_filter
  22.     *       high_pixel
  23.     *       low_pixel
  24.     *       setup_filters
  25.     *       get_filter_options
  26.     *       median_of
  27.     *       sort_elements
  28.     *       swap
  29.     *
  30.     *    Purpose:
  31.     *       These functions implement several
  32.     *       types of basic spatial frequency
  33.     *       filters.
  34.     *
  35.     *    External Calls:
  36.     *       wtiff.c - round_off_image_size
  37.     *                 create_file_if_needed
  38.     *                 write_array_into_tiff_image
  39.     *       tiff.c - read_tiff_header
  40.     *       rtiff.c - read_tiff_image
  41.     *       numcvrt.c - get_integer
  42.     *
  43.     *
  44.     *    Modifications:
  45.     *       15 February 1992 - created
  46.     *
  47.     *************************************************/
  48.  
  49. #include "cips.h"
  50.  
  51.  
  52.      /*******************************************
  53.      *
  54.      *   Define the filter masks.
  55.      *
  56.      *******************************************/
  57.  
  58. short lpf_filter_6[3][3] =
  59.    { {0, 1, 0},
  60.      {1, 2, 1},
  61.      {0, 1, 0}};
  62.  
  63. short lpf_filter_9[3][3] =
  64.    { {1, 1, 1},
  65.      {1, 1, 1},
  66.      {1, 1, 1}};
  67.  
  68. short lpf_filter_10[3][3] =
  69.    { {1, 1, 1},
  70.      {1, 2, 1},
  71.      {1, 1, 1}};
  72.  
  73. short lpf_filter_16[3][3] =
  74.    { {1, 2, 1},
  75.      {2, 4, 2},
  76.      {1, 2, 1}};
  77.  
  78. short lpf_filter_32[3][3] =
  79.    { {1,  4, 1},
  80.      {4, 12, 4},
  81.      {1,  4, 1}};
  82.  
  83. short hpf_filter_1[3][3] =
  84.    { { 0, -1,  0},
  85.      {-1,  5, -1},
  86.      { 0, -1,  0}};
  87.  
  88. short hpf_filter_2[3][3] =
  89.    { {-1, -1, -1},
  90.      {-1,  9, -1},
  91.      {-1, -1, -1}};
  92.  
  93. short hpf_filter_3[3][3] =
  94.    { { 1, -2,  1},
  95.      {-2,  5, -2},
  96.      { 1, -2,  1}};
  97.  
  98.  
  99.  
  100.  
  101.  
  102.      /*******************************************
  103.      *
  104.      *   filter_image(...
  105.      *
  106.      *   This function filters an image by using
  107.      *   a single 3x3 mask.
  108.      *
  109.      *******************************************/
  110.  
  111.  
  112. filter_image(in_name, out_name, the_image, out_image,
  113.              il, ie, ll, le, filter, type)
  114.    char   in_name[], out_name[];
  115.    int    il, ie, ll, le, type;
  116.    short  filter[3][3],
  117.           the_image[ROWS][COLS],
  118.           out_image[ROWS][COLS];
  119.  
  120. {
  121.    int    a, b, d, i, j, k,
  122.           length, max, sum, width;
  123.    struct tiff_header_struct image_header;
  124.  
  125.  
  126.    create_file_if_needed(in_name, out_name, out_image);
  127.  
  128.    read_tiff_header(in_name, &image_header);
  129.  
  130.    d = type;
  131.    if(type == 2 || type == 3) d = 1;
  132.  
  133.    max = 255;
  134.    if(image_header.bits_per_pixel == 4)
  135.       max = 16;
  136.  
  137.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  138.  
  139.          /* Do convolution over image array */
  140.    printf("\n");
  141.    for(i=1; i<ROWS-1; i++){
  142.       if( (i%10) == 0) printf("%d ", i);
  143.       for(j=1; j<COLS-1; j++){
  144.          sum = 0;
  145.          for(a=-1; a<2; a++){
  146.             for(b=-1; b<2; b++){
  147.                sum = sum +
  148.                      the_image[i+a][j+b] *
  149.                      filter[a+1][b+1];
  150.             }
  151.          }
  152.          sum               = sum/d;
  153.          if(sum < 0)   sum = 0;
  154.          if(sum > max) sum = max;
  155.          out_image[i][j]   = sum;
  156.  
  157.       }  /* ends loop over j */
  158.    }  /* ends loop over i */
  159.  
  160.    fix_edges(out_image, 1);
  161.  
  162.    write_array_into_tiff_image(out_name, out_image,
  163.                                il, ie, ll, le);
  164.  
  165. }  /* ends filter_image */
  166.  
  167.  
  168.  
  169.  
  170.      /*******************************************
  171.      *
  172.      *   high_pixel(..
  173.      *
  174.      *   This function replaces the pixel at
  175.      *   the center of a 3x3, 5x5, etc. area
  176.      *   with the max for that area.
  177.      *
  178.      *******************************************/
  179.  
  180. high_pixel(in_name, out_name, the_image, out_image,
  181.            il, ie, ll, le, size)
  182.    char   in_name[], out_name[];
  183.    int    il, ie, ll, le, size;
  184.    short  the_image[ROWS][COLS],
  185.           out_image[ROWS][COLS];
  186. {
  187.    int    a, b, count, i, j, k,
  188.           length, sd2, sd2p1, ss, width;
  189.    short  *elements;
  190.    struct tiff_header_struct image_header;
  191.  
  192.    sd2   = size/2;
  193.    sd2p1 = sd2 + 1;
  194.  
  195.       /**********************************************
  196.       *
  197.       *   Allocate the elements array large enough
  198.       *   to hold size*size shorts.
  199.       *
  200.       **********************************************/
  201.  
  202.    ss       = size*size;
  203.    elements = (short *) malloc(ss * sizeof(short));
  204.  
  205.    create_file_if_needed(in_name, out_name, out_image);
  206.  
  207.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  208.  
  209.       /***************************
  210.       *
  211.       *   Loop over image array
  212.       *
  213.       ****************************/
  214.  
  215.    printf("\n");
  216.    for(i=sd2; i<ROWS-sd2; i++){
  217.       if( (i%10) == 0) printf("%d ", i);
  218.       for(j=sd2; j<COLS-sd2; j++){
  219.          count = 0;
  220.          for(a=-sd2; a<sd2p1; a++){
  221.             for(b=-sd2; b<sd2p1; b++){
  222.                elements[count] = the_image[i+a][j+b];
  223.                count++;
  224.             }
  225.          }
  226.          sort_elements(elements, &ss);
  227.          out_image[i][j] = elements[ss-1];
  228.       }  /* ends loop over j */
  229.    }  /* ends loop over i */
  230.  
  231.    fix_edges(out_image, sd2);
  232.  
  233.    write_array_into_tiff_image(out_name, out_image,
  234.                                il, ie, ll, le);
  235.  
  236.    free(elements);
  237.  
  238. }  /* ends high_pixel */
  239.  
  240.  
  241.  
  242.  
  243.      /*******************************************
  244.      *
  245.      *   low_pixel(..
  246.      *
  247.      *   This function replaces the pixel at
  248.      *   the center of a 3x3, 5x5, etc. area
  249.      *   with the min for that area.
  250.      *
  251.      *******************************************/
  252.  
  253.  
  254. low_pixel(in_name, out_name, the_image, out_image,
  255.           il, ie, ll, le, size)
  256.    char   in_name[], out_name[];
  257.    int    il, ie, ll, le, size;
  258.    short  the_image[ROWS][COLS],
  259.           out_image[ROWS][COLS];
  260.  
  261. {
  262.    int    a, b, count, i, j, k,
  263.           length, sd2, sd2p1, ss, width;
  264.    short  *elements;
  265.    struct tiff_header_struct image_header;
  266.  
  267.    sd2   = size/2;
  268.    sd2p1 = sd2 + 1;
  269.  
  270.       /**********************************************
  271.       *
  272.       *   Allocate the elements array large enough
  273.       *   to hold size*size shorts.
  274.       *
  275.       **********************************************/
  276.  
  277.    ss       = size*size;
  278.    elements = (short *) malloc(ss * sizeof(short));
  279.  
  280.    create_file_if_needed(in_name, out_name, out_image);
  281.  
  282.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  283.  
  284.       /***************************
  285.       *
  286.       *   Loop over image array
  287.       *
  288.       ****************************/
  289.  
  290.    printf("\n");
  291.    for(i=sd2; i<ROWS-sd2; i++){
  292.       if( (i%10) == 0) printf("%d ", i);
  293.       for(j=sd2; j<COLS-sd2; j++){
  294.          count = 0;
  295.          for(a=-sd2; a<sd2p1; a++){
  296.             for(b=-sd2; b<sd2p1; b++){
  297.                elements[count] = the_image[i+a][j+b];
  298.                count++;
  299.             }
  300.          }
  301.          sort_elements(elements, &ss);
  302.          out_image[i][j] = elements[0];
  303.       }  /* ends loop over j */
  304.    }  /* ends loop over i */
  305.  
  306.    fix_edges(out_image, sd2);
  307.  
  308.    write_array_into_tiff_image(out_name, out_image,
  309.                                il, ie, ll, le);
  310.  
  311.    free(elements);
  312.  
  313. }  /* ends low_pixel */
  314.  
  315.  
  316.  
  317.  
  318.      /*******************************************
  319.      *
  320.      *   median_filter(..
  321.      *
  322.      *   This function performs a median filter
  323.      *   on an image using a size (3x3, 5x5, etc.)
  324.      *   specified in the call.
  325.      *
  326.      *******************************************/
  327.  
  328. median_filter(in_name, out_name, the_image, out_image,
  329.               il, ie, ll, le, size)
  330.    char   in_name[], out_name[];
  331.    int    il, ie, ll, le, size;
  332.    short  the_image[ROWS][COLS],
  333.           out_image[ROWS][COLS];
  334.  
  335. {
  336.    int    a, b, count, i, j, k,
  337.           length, sd2, sd2p1, ss, width;
  338.    short  *elements;
  339.    struct tiff_header_struct image_header;
  340.  
  341.    sd2   = size/2;
  342.    sd2p1 = sd2 + 1;
  343.  
  344.       /**********************************************
  345.       *
  346.       *   Allocate the elements array large enough
  347.       *   to hold size*size shorts.
  348.       *
  349.       **********************************************/
  350.  
  351.    ss       = size*size;
  352.    elements = (short *) malloc(ss * sizeof(short));
  353.  
  354.    create_file_if_needed(in_name, out_name, out_image);
  355.  
  356.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  357.  
  358.       /***************************
  359.       *
  360.       *   Loop over image array
  361.       *
  362.       ****************************/
  363.  
  364.    printf("\n");
  365.    for(i=sd2; i<ROWS-sd2; i++){
  366.       if( (i%10) == 0) printf("%d ", i);
  367.       for(j=sd2; j<COLS-sd2; j++){
  368.          count = 0;
  369.          for(a=-sd2; a<sd2p1; a++){
  370.             for(b=-sd2; b<sd2p1; b++){
  371.                elements[count] = the_image[i+a][j+b];
  372.                count++;
  373.             }
  374.          }
  375.          out_image[i][j] = median_of(elements, &ss);
  376.       }  /* ends loop over j */
  377.    }  /* ends loop over i */
  378.  
  379.    fix_edges(out_image, sd2);
  380.  
  381.    write_array_into_tiff_image(out_name, out_image,
  382.                                il, ie, ll, le);
  383.  
  384.    free(elements);
  385.  
  386. }  /* ends median_filter */
  387.  
  388.  
  389.  
  390.     /***********************************************
  391.     *
  392.     *    median_of(...
  393.     *
  394.     *    This function finds and returns the
  395.     *    median value of the elements array.
  396.     *
  397.     *    As a side result, it also sorts the
  398.     *    elements array.
  399.     *
  400.     ***********************************************/
  401.  
  402. median_of(elements, count)
  403.    int   *count;
  404.    short elements[];
  405. {
  406.    short median;
  407.  
  408.    sort_elements(elements, count);
  409.    median = elements[*count/2];
  410.    return(median);
  411. }  /* ends median_of */
  412.  
  413.  
  414.  
  415.     /***********************************************
  416.     *
  417.     *    sort_elements(...
  418.     *
  419.     *    This function performs a simple bubble
  420.     *    sort on the elements from the median
  421.     *    filter.
  422.     *
  423.     ***********************************************/
  424.  
  425. sort_elements(elements, count)
  426.    int   *count;
  427.    short elements[];
  428. {
  429.    int i, j;
  430.    j = *count;
  431.    while(j-- > 1){
  432.       for(i=0; i<j; i++){
  433.          if(elements[i] > elements[i+1])
  434.             swap(&elements[i], &elements[i+1]);
  435.       }
  436.    }
  437. }  /* ends sort_elements */
  438.  
  439.  
  440.  
  441.     /***********************************************
  442.     *
  443.     *    swap(...
  444.     *
  445.     *    This function swaps two shorts.
  446.     *
  447.     ***********************************************/
  448.  
  449. swap(a, b)
  450.    short *a, *b;
  451. {
  452.    short temp;
  453.    temp  = *a;
  454.    *a    = *b;
  455.    *b    = temp;
  456. }  /* ends swap */
  457.  
  458.  
  459.  
  460.     /************************************************
  461.     *
  462.     *    setup_filters(...
  463.     *
  464.     *    This function copies the filter mask
  465.     *    values defined at the top of this file
  466.     *    into the filter array.
  467.     *
  468.     ************************************************/
  469.  
  470.  
  471. setup_filters(filter_type, low_high, filter)
  472.    char   low_high[];
  473.    int    filter_type;
  474.    short  filter[3][3];
  475. {
  476.    int i, j;
  477.  
  478.    if(low_high[0] == 'l'  || low_high[0] =='L'){
  479.       if(filter_type == 6){
  480.          for(i=0; i<3; i++){
  481.            for(j=0; j<3; j++){
  482.              filter[i][j] = lpf_filter_6[i][j];
  483.            }
  484.          }
  485.       }  /* ends if filter_type == 6 */
  486.  
  487.       if(filter_type == 9){
  488.          for(i=0; i<3; i++){
  489.            for(j=0; j<3; j++){
  490.              filter[i][j] = lpf_filter_9[i][j];
  491.            }
  492.          }
  493.       }  /* ends if filter_type == 9 */
  494.  
  495.       if(filter_type == 10){
  496.          for(i=0; i<3; i++){
  497.            for(j=0; j<3; j++){
  498.              filter[i][j] = lpf_filter_10[i][j];
  499.            }
  500.          }
  501.       }  /* ends if filter_type == 10 */
  502.  
  503.  
  504.       if(filter_type == 16){
  505.          for(i=0; i<3; i++){
  506.            for(j=0; j<3; j++){
  507.              filter[i][j] = lpf_filter_16[i][j];
  508.            }
  509.          }
  510.       }  /* ends if filter_type == 16 */
  511.  
  512.  
  513.       if(filter_type == 32){
  514.          for(i=0; i<3; i++){
  515.            for(j=0; j<3; j++){
  516.              filter[i][j] = lpf_filter_32[i][j];
  517.            }
  518.          }
  519.       }  /* ends if filter_type == 32 */
  520.    }  /* ends low pass filter */
  521.  
  522.  
  523.  
  524.  
  525.    if(low_high[0] == 'h'  || low_high[0] =='H'){
  526.       if(filter_type == 1){
  527.          for(i=0; i<3; i++){
  528.            for(j=0; j<3; j++){
  529.              filter[i][j] = hpf_filter_1[i][j];
  530.            }
  531.          }
  532.       }  /* ends if filter_type == 1 */
  533.  
  534.       if(filter_type == 2){
  535.          for(i=0; i<3; i++){
  536.            for(j=0; j<3; j++){
  537.              filter[i][j] = hpf_filter_2[i][j];
  538.            }
  539.          }
  540.       }  /* ends if filter_type == 2 */
  541.  
  542.       if(filter_type == 3){
  543.          for(i=0; i<3; i++){
  544.            for(j=0; j<3; j++){
  545.              filter[i][j] = hpf_filter_3[i][j];
  546.            }
  547.          }
  548.       }  /* ends if filter_type == 3 */
  549.    }  /* ends high pass filter */
  550.  
  551. }  /* ends setup_filters */
  552.  
  553.  
  554.  
  555.     /***********************************************
  556.     *
  557.     *    get_filter_options(...
  558.     *
  559.     *    This function queries the user for the
  560.     *    parameters needed to perform filtering.
  561.     *
  562.     ***********************************************/
  563.  
  564.  
  565. get_filter_options(filter_type, low_high)
  566.     char low_high[];
  567.     int  *filter_type;
  568. {
  569.     int not_finished, response;
  570.     not_finished = 1;
  571.     while(not_finished){
  572.  
  573.       printf("\nThe filter options are:\n");
  574.       printf("\n\t1. Type of filter is %d",
  575.               *filter_type);
  576.       printf(
  577.          "\n\t      (6, 9, 10, 16, 32 for low pass)");
  578.       printf("\n\t      (1, 2, 3 for high pass)");
  579.       printf("\n\t2. Low or High Pass filter is %s",
  580.              low_high);
  581.       printf("\n\t      l=low pass h=high pass "
  582.              "m=median filter "
  583.              "\n\t      i=high pixel o=low pixel");
  584.       printf("\n\t      Type is the nxn size for"
  585.             " median, high pixel, and low pixel");
  586.       printf("\n\nEnter choice (0 = no change) _\b");
  587.  
  588.  
  589.       get_integer(&response);
  590.  
  591.       if(response == 0){
  592.         not_finished = 0;
  593.       }
  594.  
  595.       if(response == 1){
  596.         printf("\n\nEnter type of filter");
  597.         printf("\n  _\b");
  598.         get_integer(filter_type);
  599.       }
  600.  
  601.       if(response == 2){
  602.         printf("\n\nEnter l=low pass h=high pass "
  603.               "m=median filter i=high pixel "
  604.               "o=low pixel");
  605.         printf("\n  _\b");
  606.         gets(low_high);
  607.       }
  608.     }  /* ends while not_finished */
  609.  
  610. }  /* ends get_filter_options */
  611.  
  612.  
  613.    /**************************************************
  614.    *
  615.    *   file d:\cips\display.c
  616.    *
  617.    *   Functions: This file contains
  618.    *      display_image
  619.    *      display_image_portion
  620.    *      display_menu_for_display_image
  621.    *      map_16_shades_of_gray
  622.    *      my_map_64_shades_of_gray
  623.    *      transform_the_colors
  624.    *
  625.    *   Purpose:
  626.    *      These functions display images on a the
  627.    *      monitor.
  628.    *
  629.    *      NOTE: This file is full of Microsoft
  630.    *            specific code.  The PC C compiler
  631.    *            makers all have their own routines
  632.    *            for making dots appear on the
  633.    *            screen.  I put the statement
  634.    *            MSC 6.0 next to these calls.
  635.    *
  636.    *
  637.    *   External Calls:
  638.    *      rtiff.c - read_tiff_image
  639.    *      cips.c - my_clear_text_screen
  640.    *      hist.c - zero_histogram
  641.    *               calculate_histogram
  642.    *               perform_histogram_equalization
  643.    *               display_histogram
  644.    *
  645.    *   Modifications:
  646.    *      17 June 1987 - created
  647.    *      August 1990 - extension modifications for use
  648.    *          in the C Image Processing System.
  649.    *
  650.    ***************************************************/
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.    /***************************
  659.    *
  660.    *   display_image(...
  661.    *
  662.    ****************************/
  663.  
  664.  
  665. display_image(file_name, image, il, ie, ll, le,
  666.               image_header, monitor_type, 
  667.               color_transform, invert, image_colors, 
  668.               display_colors, show_hist, title)
  669.    char    color_transform[],
  670.            file_name[],
  671.            monitor_type[],
  672.            title[];
  673.    int     display_colors,
  674.            image_colors,
  675.            invert,
  676.            il,
  677.            ie,
  678.            ll,
  679.            le,
  680.            show_hist;
  681.    short   image[ROWS][COLS];
  682.    struct  tiff_header_struct *image_header;
  683. {
  684.    char  channels[80],
  685.          response[80];
  686.  
  687.    int   a,
  688.          b,
  689.          c,
  690.          channel,
  691.          count,
  692.          display_mode,
  693.          dx_offset,
  694.          dy_offset,
  695.          key,
  696.          horizontal,
  697.          len,
  698.          max_horizontal,
  699.          max_vertical,
  700.          not_finished,
  701.          q,
  702.          r,
  703.          vertical,
  704.          x_offset,
  705.          y_offset;
  706.  
  707.    unsigned int block,
  708.                 color,
  709.                 i,
  710.                 j,
  711.                 x,
  712.                 y;
  713.    unsigned long histogram[256], new_hist[256];
  714.  
  715.  
  716.      /**********************************************
  717.      *
  718.      *   If you want to display the histogram and 
  719.      *   do not want to perform hist equalization, 
  720.      *   then zero the histogram for calculations.
  721.      *
  722.      **********************************************/
  723.  
  724.    if(  (show_hist == 1)   &&
  725.         (color_transform[0] != 'H'))
  726.       zero_histogram(histogram);
  727.  
  728.    not_finished = 1;
  729.    while(not_finished){
  730.  
  731.  
  732.       if(display_colors == 16){
  733.          if(monitor_type[0] == 'V'){
  734.             horizontal   = 4;
  735.         vertical = 6;
  736.         display_mode = VRES16COLOR; /* MSC 6.0 */
  737.          }  /* ends if V */
  738.          if(monitor_type[0] == 'E'){
  739.             horizontal   = 3;
  740.             vertical     = 6;
  741.             display_mode = ERESCOLOR; /* MSC 6.0 */
  742.          }  /* ends if E */
  743.  
  744.       }  /* ends if colors == 16 */
  745.  
  746.       else{
  747.          horizontal   = 2;
  748.          vertical     = 2;
  749.          display_mode = MAXCOLORMODE; /* MSC 6.0 */
  750.       }
  751.  
  752.         /********************************************
  753.         *
  754.         *   Somehow, my dx and dy offsets are 
  755.         *   backwards from my horizontal and vertical 
  756.         *   variables. Trying to center the images 
  757.         *   on the screen. March 21 1992
  758.         *
  759.         ********************************************/
  760.  
  761.       max_horizontal = (image_header->image_length+50)
  762.                        /COLS;
  763.       max_vertical   = (image_header->image_width+50)
  764.                        /ROWS;
  765.  
  766.       dy_offset = ((horizontal-max_horizontal)/2)
  767.                   *COLS + 50;
  768.       dx_offset = ((vertical-max_vertical)/2)
  769.                   *ROWS + 20;
  770.  
  771.       if(max_horizontal > horizontal) dy_offset = 0;
  772.       if(max_vertical > vertical)     dx_offset = 0;
  773.  
  774.       if(horizontal > max_horizontal) 
  775.          horizontal = max_horizontal;
  776.       if(vertical > max_vertical)     
  777.          vertical   = max_vertical;
  778.  
  779.  
  780.         /****************************************
  781.         *
  782.         *   If color transform wants histogram
  783.         *   equalization, then read in the
  784.         *   image arrays and calculate the
  785.         *   histogram.   Zero both the histogram
  786.         *   and the new_hist.  You will need the
  787.         *   new_hist if you want to display the
  788.         *   equalized hist.
  789.         *
  790.         *****************************************/
  791.  
  792.       if(color_transform[0] == 'H'){
  793.          count = 1;
  794.          zero_histogram(histogram);
  795.          zero_histogram(new_hist);
  796.          for(a=0; a<vertical; a++){
  797.             for(b=0; b<horizontal; b++){
  798.  
  799.                x = a*COLS;
  800.                y = b*ROWS;
  801.  
  802.                printf(
  803.                   "\nDISPLAY> Calculating histogram");
  804.                printf(" %d of %d",
  805.                   count,vertical*horizontal);
  806.                count++;
  807.                read_tiff_image(file_name, image, il+y,
  808.                             ie+x, ll+y, le+x);
  809.                calculate_histogram(image, histogram);
  810.  
  811.             }  /* ends loop over b */
  812.          }  /* ends loop over a */
  813.       }  /* ends if display_mode == H */
  814.  
  815.  
  816.         /* set graphics mode */
  817.  
  818.    my_setvideomode(display_mode); /* MSC 6.0 */
  819.    if(display_colors == 16) 
  820.       map_16_shades_of_gray(display_mode);
  821.    if(display_colors == 256) 
  822.       my_map_64_shades_of_gray();
  823.  
  824.  
  825.         /****************************************
  826.         *
  827.         *   Loop over this size and
  828.         *   read and display ROWSxCOLS arrays.
  829.         *
  830.         *   If you want to show the histogram AND
  831.         *   do not want to do hist equalization
  832.         *   then calculate the hist from the
  833.         *   original image array.
  834.         *
  835.         *   If you want to do hist equalization
  836.         *   then calculate the new_hist AFTER
  837.         *   the image has been equalized by the
  838.         *   the transform_the_colors function.
  839.         *
  840.         *   NOTE: Remember that the function
  841.         *   transform_the_colors changes the
  842.         *   gray shade values in image array.
  843.         *
  844.         *****************************************/
  845.  
  846.         /*****************************************
  847.         *
  848.         *   These statements place a gray 
  849.         *   background across the display area of 
  850.         *   a VGA screen.  This reduces the 
  851.         *   contrast between the screen background 
  852.         *   and the images you display. This makes 
  853.         *   it easier to take photos.
  854.         *
  855.         *******************************************/
  856.  
  857.       /* MSC 6.0 */
  858.       my_setlinestyle(0xFFFF);
  859.       my_setcolor(10);
  860.       for(i=0; i<640;i++){
  861.          my_moveto(i, 0);
  862.          my_lineto(i, 480);
  863.       }
  864.  
  865.       for(a=0; a<vertical; a++){
  866.          for(b=0; b<horizontal; b++){
  867.  
  868.             x = a*COLS;
  869.             y = b*ROWS;
  870.             read_tiff_image(file_name, image, il+y,
  871.                             ie+x, ll+y, le+x);
  872.             if(  (show_hist == 1)  &&
  873.                  (color_transform[0] != 'H'))
  874.                calculate_histogram(image, histogram);
  875.  
  876.             transform_the_colors(image, 
  877.                                  color_transform,
  878.                                  display_colors,
  879.                                  image_colors, 
  880.                                  histogram,
  881.                                  horizontal, 
  882.                                  vertical);
  883.  
  884.             if(color_transform[0] == 'H')
  885.                calculate_histogram(image, new_hist);
  886.           display_image_portion(image, x+dx_offset,
  887.                                 y+dy_offset, 
  888.                                 display_colors,
  889.                                 image_colors, invert);
  890.          }        /* ends loop over b */
  891.       }        /* ends loop over a */
  892.  
  893.           /*******************************************
  894.           *
  895.           *   Put in these statements to print a title 
  896.           *   at the bottom of the display.  This is 
  897.           *   nice for taking photos or articles 
  898.           *   because it tells the reader what you 
  899.           *   are trying to do.
  900.           *
  901.           ********************************************/
  902.  
  903.       /* MSC 6.0 */
  904.       my_settextcolor(10);
  905.       my_setbkcolor(1L);
  906.       len = strlen(title);
  907.       len = 40 - (len/2);
  908.       my_settextposition(28, len);
  909.       my_outtext(title);
  910.  
  911.          /***************************
  912.          *
  913.          *   if show_hist == 1 then
  914.          *   display the histogram
  915.          *   in the lower right hand
  916.          *   corner of screen
  917.          *
  918.          *   If hist equalization was
  919.          *   performed then show the
  920.          *   new_hist.  If it wasn't
  921.          *   done then show the original
  922.          *   histogram.
  923.          *
  924.          ****************************/
  925.  
  926.       if(show_hist == 1){
  927.          if(monitor_type[0] == 'V')
  928.             y_offset = 470;
  929.          if(monitor_type[0] == 'E')
  930.             y_offset = 310;
  931.          x_offset = 380;
  932.          if(color_transform[0] == 'H')
  933.             display_histogram(new_hist, x_offset,
  934.                    y_offset, 5, 9);
  935.          else{
  936.             display_histogram(histogram, x_offset,
  937.                    y_offset, 5, 9);
  938.                /* xtra stuff for cips9
  939.             display_histogram(histogram, 45,
  940.                    370, 5, 9); */
  941.  
  942.                /*********************************
  943.                *
  944.                *   Change to show smoothed
  945.                *   histogram next to the regular
  946.                *   histogram.
  947.                *
  948.                **********************************/
  949.  
  950.                /* xtra stuff for cips9
  951.             smooth_histogram(histogram);
  952.             display_histogram(histogram, 345,
  953.                    370, 5, 9); */
  954.          }
  955.       }
  956.  
  957.       gets(response);
  958.       printf("\nEnter 0 to quit 1 to do again");
  959.       get_integer(¬_finished);
  960.  
  961.           /* set display back to text mode */
  962.       my_clear_text_screen();
  963.  
  964.  
  965.    }  /* ends while not_finished  */
  966.  
  967. }  /* ends main  */
  968.  
  969.  
  970.  
  971.  
  972.    /***********************************************
  973.    *
  974.    *   display_menu_for_display_image(
  975.    *
  976.    ************************************************/
  977.  
  978. display_menu_for_display_image(image_colors, 
  979.                               display_colors,
  980.                               invert, color_transform,
  981.                               monitor_type,
  982.                               show_hist)
  983.    char color_transform[], monitor_type[];
  984.    int  *invert, *image_colors, 
  985.         *display_colors, *show_hist;
  986. {
  987.    char response[80];
  988.    int  int_response, not_finished, r;
  989.  
  990.    not_finished = 1;
  991.    while(not_finished){
  992.       printf("\n\nDISPLAY> Enter choice "
  993.              "(0 for no change) ");
  994.       printf("\nDISPLAY> 1. Invert is %d (1=on 0=off)",
  995.              *invert);
  996.       printf("\nDISPLAY> 2. Color Transform-- %s",
  997.              color_transform);
  998.       printf("\nDISPLAY> 3. Input image has %d colors",
  999.              *image_colors);
  1000.       printf("\nDISPLAY> 4. Display will show %d colors",
  1001.              *display_colors);
  1002.       printf("\nDISPLAY> 5. Monitor type is %s",
  1003.              monitor_type);
  1004.       printf("\nDISPLAY> 6. Histogram is %d", 
  1005.              *show_hist);
  1006.       printf("  (1=show 0=don't show)");
  1007.       printf("\nDISPLAY> _\b");
  1008.       get_integer(&r);
  1009.  
  1010.       if(r == 0){
  1011.          not_finished = 0;
  1012.       }
  1013.  
  1014.       if(r == 1){
  1015.          printf("\nDISPLAY> Enter 1 for invert on");
  1016.          printf(" 0 for invert off");
  1017.          printf("\nDISPLAY> ___");
  1018.          get_integer(&int_response);
  1019.          *invert = int_response;
  1020.       }  /* ends if r == 1 */
  1021.  
  1022.       if(r == 2){
  1023.          printf("\nDISPLAY> Enter the new color "
  1024.                 "transform mode ");
  1025.          printf("\nDISPLAY> (S) Straight mode");
  1026.          printf("   (H) Histogram Equalization");
  1027.          printf("\nDISPLAY> _\b");
  1028.          gets(response);
  1029.          if((response[0] == 'S') ||
  1030.             (response[0] == 's'))
  1031.                strcpy(color_transform, 
  1032.                       "Straight mode");
  1033.          else
  1034.                strcpy(color_transform,
  1035.                 "Histogram Equalization mode");
  1036.       }  /* ends if r == 2  */
  1037.  
  1038.       if(r == 3){
  1039.          printf("\nDISPLAY> Enter the number "
  1040.                 "of colors");
  1041.          printf(" in the input image");
  1042.          printf("\nDISPLAY> ___");
  1043.          get_integer(&int_response);
  1044.          *image_colors = int_response;
  1045.       }  /* ends if r == 3 */
  1046.  
  1047.       if(r == 4){
  1048.          printf(
  1049.           "\nDISPLAY> Enter the number of colors "
  1050.           "for the display");
  1051.          printf("\nDISPLAY> ___");
  1052.          get_integer(&int_response);
  1053.          *display_colors = int_response;
  1054.       }  /* ends if r == 4 */
  1055.  
  1056.       if(r == 5){
  1057.          printf("\nDISPLAY> Enter the new monitor type");
  1058.          printf("\nDISPLAY> (E) EGA   (V) VGA");
  1059.          printf("   (C) CGA   (M) Monochrome");
  1060.          printf("\nDISPLAY> _\b");
  1061.          gets(response);
  1062.          if((response[0] == 'E') ||
  1063.             (response[0] == 'e'))
  1064.             strcpy(monitor_type, "EGA");
  1065.       if((response[0] == 'V') ||
  1066.          (response[0] == 'v'))
  1067.             strcpy(monitor_type, "VGA");
  1068.       if((response[0] == 'C') ||
  1069.          (response[0] == 'c'))
  1070.             strcpy(monitor_type, "CGA");
  1071.       if((response[0] == 'M') ||
  1072.          (response[0] == 'm'))
  1073.             strcpy(monitor_type, "Monochrome");
  1074.       }  /* ends if r == 5  */
  1075.  
  1076.       if(r == 6){
  1077.          printf(
  1078.             "\nDISPLAY> Enter 1 for show histogram "
  1079.             "0 for don't");
  1080.          printf("\nDISPLAY> ___");
  1081.          get_integer(&int_response);
  1082.          *show_hist = int_response;
  1083.       }  /* ends if r == 6 */
  1084.  
  1085.    }  /* ends while not_finished  */
  1086. }  /* ends display_menu  */
  1087.  
  1088.  
  1089.  
  1090.  
  1091.    /********************************
  1092.    *
  1093.    *   display_image_portion(...
  1094.    *
  1095.    *********************************/
  1096.  
  1097. display_image_portion(image, x, y, display_colors, 
  1098.                       image_colors, invert)
  1099.    int      invert, display_colors, image_colors;
  1100.    short    image[ROWS][COLS];
  1101.    unsigned int x, y;
  1102. {
  1103.    unsigned int color, i, j;
  1104.  
  1105.       if(invert == 1){
  1106.         for(i=0; i<ROWS; i++)
  1107.            for(j=0; j<COLS; j++)
  1108.               image[i][j] = (display_colors-1)
  1109.                              - image[i][j];
  1110.       }  /* ends if invert == 1 */
  1111.  
  1112.       for(i=0; i<ROWS; i++){
  1113.          for(j=0; j<COLS; j++){
  1114.  
  1115.         /* MSC 6.0 */
  1116.         my_setcolor(image[i][j]);
  1117.         my_setpixel(j+x, i+y);
  1118. /*****
  1119. my_set_pixel(j+x, i+y, image[i][j]);
  1120. ******/
  1121.  
  1122.          }  /* ends loop over j  */
  1123.       }     /* ends loop over i  */
  1124.  
  1125. }  /* ends display_image_portion  */
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131.    /**********************************************
  1132.    *
  1133.    *   map_16_shades_of_gray(...
  1134.    *
  1135.    *   This function maps 16 shades of gray into
  1136.    *   the first 16 color indices.  This allows
  1137.    *   you to display a true "black and white"
  1138.    *   image on a color monitor.
  1139.    *
  1140.    *********************************************/
  1141.  
  1142. map_16_shades_of_gray(display_mode)
  1143.    int display_mode;
  1144. {
  1145.    /* all MSC 6.0 statements */
  1146. my_setvideomode(display_mode);
  1147. my_remappalette(0,  0x000000L);
  1148. my_remappalette(1,  0x040404L);
  1149. my_remappalette(2,  0x080808L);
  1150. my_remappalette(3,  0x0c0c0cL);
  1151. my_remappalette(4,  0x101010L);
  1152. my_remappalette(5,  0x141414L);
  1153. my_remappalette(6,  0x181818L);
  1154. my_remappalette(7,  0x1c1c1cL);
  1155. my_remappalette(8,  0x202020L);
  1156. my_remappalette(9,  0x242424L);
  1157. my_remappalette(10, 0x282828L);
  1158. my_remappalette(11, 0x2c2c2cL);
  1159. my_remappalette(12, 0x303030L);
  1160. my_remappalette(13, 0x343434L);
  1161. my_remappalette(14, 0x383838L);
  1162. my_remappalette(15, 0x3f3f3fL);
  1163. }
  1164.  
  1165.  
  1166.  
  1167.  
  1168.    /*********************************************
  1169.    *
  1170.    *   transform_the_colors(...
  1171.    *
  1172.    *   This function transforms the gray shades
  1173.    *   in the image array for display.  It can either
  1174.    *   do it in straight mode by multiplying or
  1175.    *   dividing or it can do it with hist
  1176.    *   equalization by calling the function
  1177.    *   perform_histogram_equalization.
  1178.    *
  1179.    *************************************************/
  1180.  
  1181. transform_the_colors(image, color_transform,
  1182.                      display_colors, image_colors,
  1183.                      histogram, horizontal,
  1184.                      vertical)
  1185.    char   color_transform[];
  1186.    int    display_colors, horizontal,
  1187.           image_colors, vertical;
  1188.    short  image[ROWS][COLS];
  1189.    unsigned long histogram[];
  1190. {
  1191.    int         color, i, j;
  1192.    float new_grays, area;
  1193.    unsigned long x;
  1194.  
  1195.    if(color_transform[0] == 'S'){
  1196.       for(i=0; i<ROWS; i++){
  1197.          for(j=0; j<COLS; j++){
  1198.  
  1199.             if( (display_colors == 16) &&
  1200.                 (image_colors  == 256))
  1201.                color = image[i][j]/16;
  1202.             if( (display_colors == 16) &&
  1203.                 (image_colors  == 16))
  1204.                color = image[i][j];
  1205.             if( (display_colors == 256) &&
  1206.                 (image_colors  == 256))
  1207.                color = image[i][j];
  1208.             if( (display_colors == 256) &&
  1209.                 (image_colors  == 16))
  1210.                color = image[i][j]*16;
  1211.  
  1212.             image[i][j] = color;
  1213.  
  1214.          }  /* ends loop over j        */
  1215.       }        /* ends loop over i        */
  1216.    }  /* ends if transform is straight */
  1217.  
  1218.    if(color_transform[0] == 'H'){
  1219.  
  1220.       area      = ((long)(vertical)) *
  1221.                   ((long)(horizontal));
  1222.       area      = area*10000.0;
  1223.       new_grays = display_colors;
  1224.  
  1225.       perform_histogram_equalization(image, histogram,
  1226.                                      new_grays, area);
  1227.  
  1228.    }  /* ends if transform is hist equalization */
  1229.  
  1230. }  /* ends transform_the_colors */
  1231.  
  1232.  
  1233.  
  1234.  
  1235.    /*************************************************
  1236.    *
  1237.    *   file d:\cips\djet.c
  1238.    *
  1239.    *   Functions: This file contains
  1240.    *      end_graphics_mode
  1241.    *      get_graphics_caption
  1242.    *      print_bytes
  1243.    *      print_graphics_image
  1244.    *      print_original_200_row
  1245.    *      select_300_dpi_resolution
  1246.    *      select_full_graphics_mode
  1247.    *      set_horizontal_offset
  1248.    *      set_raster_width
  1249.    *      start_raster_graphics
  1250.    *
  1251.    *   Purpose:
  1252.    *      These functions print a 200x200 image using
  1253.    *      dithering to an HP DeskJet or compatable 
  1254.    *      (Laserjet). This uses an 8x8 matrix which 
  1255.    *      gives 64 shades of gray.
  1256.    *
  1257.    *   External Calls:
  1258.    *          rtiff.c - read_tiff_image
  1259.    *           hist.c - zero_histogram
  1260.    *                    calculate_histogram
  1261.    *                    perform_histogram_equalization
  1262.    *
  1263.    *
  1264.    *   Modifications:
  1265.    *      January 1991 - created
  1266.    *      25 August 1991 - modified for use in the
  1267.    *         C Image Processing System.
  1268.    *
  1269.     ZDDDDD?   ZDDDDD?
  1270.     3     3   3     3   The function print_graphics_image
  1271.     3     3   3     3   begins with 2 100x100 image arrays
  1272.     3     3   3     3
  1273.     3     3   3     3
  1274.     @DDDDDY   @DDDDDY
  1275.  
  1276.     ZDDDDDDDDDDDDDDD?
  1277.     3               3   It joins them into
  1278.     3               3   1 100x200 image array
  1279.     3               3
  1280.     3               3
  1281.     @DDDDDDDDDDDDDDDY
  1282.  
  1283.     ZDDDDDDDDDDDDDDD?
  1284.     @DDDDDDDDDDDDDDDY
  1285.     ZDDDDDDDDDDDDDDD?
  1286.     @DDDDDDDDDDDDDDDY
  1287.            .            It loops and creates
  1288.            .            100 200 element image arrays
  1289.            .
  1290.     ZDDDDDDDDDDDDDDD?
  1291.     @DDDDDDDDDDDDDDDY
  1292.  
  1293.  
  1294.           The function print_original_200_row 
  1295.           receives a 200 element array
  1296.     ZBDDDDDDDDDDDDDDDDDDDDDDDDDDB?
  1297.     @ADDDDDDDDDDDDDDDDDDDDDDDDDDAY
  1298.  
  1299.           This array is transformed into a 8x200 
  1300.           array of characters called 'row'
  1301.     ZDDDDDDDDD ... ~DDDDDDD?
  1302.     CDDDDDDDDD ... ~DDDDDDD4
  1303.     CDDDDDDDDD ... ~DDDDDDD4
  1304.     CDDDDDDDDD ... ~DDDDDDD4
  1305.     CDDDDDDDDD ... ~DDDDDDD4
  1306.     CDDDDDDDDD ... ~DDDDDDD4
  1307.     CDDDDDDDDD ... ~DDDDDDD4
  1308.     CDDDDDDDDD ... ~DDDDDDD4
  1309.     @DDDDDDDDD ... ~DDDDDDDY
  1310.  
  1311.           Each column of this array is a 1x8 character
  1312.           array which is an 8-bit x 8-bit array
  1313.     IMM;
  1314.     :  :
  1315.     HMM<
  1316.           Each row of 'row' is passed to the funnction 
  1317.           print_bytes for graphics printing
  1318.  
  1319.  
  1320.  
  1321.  
  1322.  
  1323.  
  1324.    ***************************************************/
  1325.  
  1326.  
  1327.  
  1328. #define ESCAPE 27
  1329. #define FORMFEED  '\014'
  1330.  
  1331. short r[200];
  1332.  
  1333.  
  1334.  
  1335.       /*******************************************
  1336.       *
  1337.       *   The patterns array holds the rows to the
  1338.       *   8x8 matrices used for printing
  1339.       *   shades of gray.
  1340.       *
  1341.       ********************************************/
  1342.  
  1343. char patterns[64][8] =
  1344.    { {255, 255, 255, 255, 255, 255, 255, 255},
  1345.      {255, 255, 255, 255, 255, 255, 255, 127},
  1346.      {255, 255, 255, 255, 255, 255, 255,  63},
  1347.      {255, 255, 255, 255, 255, 255, 255,  31},
  1348.      {255, 255, 255, 255, 255, 255, 255,  15},
  1349.      {255, 255, 255, 255, 255, 255, 255,   7},
  1350.      {255, 255, 255, 255, 255, 255, 255,   3},
  1351.      {255, 255, 255, 255, 255, 255, 255,   1},
  1352.      {255, 255, 255, 255, 255, 255, 255,   0},
  1353.      {255, 255, 255, 255, 255, 255, 127,   0},
  1354.      {255, 255, 255, 255, 255, 255,  63,   0},
  1355.      {255, 255, 255, 255, 255, 255,  31,   0},
  1356.      {255, 255, 255, 255, 255, 255,  15,   0},
  1357.      {255, 255, 255, 255, 255, 255,   7,   0},
  1358.      {255, 255, 255, 255, 255, 255,   3,   0},
  1359.      {255, 255, 255, 255, 255, 255,   1,   0},
  1360.      {255, 255, 255, 255, 255, 255,   0,   0},
  1361.      {255, 255, 255, 255, 255, 127,   0,   0},
  1362.      {255, 255, 255, 255, 255,  63,   0,   0},
  1363.      {255, 255, 255, 255, 255,  31,   0,   0},
  1364.      {255, 255, 255, 255, 255,  15,   0,   0},
  1365.      {255, 255, 255, 255, 255,   7,   0,   0},
  1366.      {255, 255, 255, 255, 255,   3,   0,   0},
  1367.      {255, 255, 255, 255, 255,   1,   0,   0},
  1368.      {255, 255, 255, 255, 255,   0,   0,   0},
  1369.      {255, 255, 255, 255, 127,   0,   0,   0},
  1370.      {255, 255, 255, 255,  63,   0,   0,   0},
  1371.      {255, 255, 255, 255,  31,   0,   0,   0},
  1372.      {255, 255, 255, 255,  15,   0,   0,   0},
  1373.      {255, 255, 255, 255,   7,   0,   0,   0},
  1374.      {255, 255, 255, 255,   3,   0,   0,   0},
  1375.      {255, 255, 255, 255,   1,   0,   0,   0},
  1376.      {255, 255, 255, 255,   0,   0,   0,   0},
  1377.      {255, 255, 255, 127,   0,   0,   0,   0},
  1378.      {255, 255, 255,  63,   0,   0,   0,   0},
  1379.      {255, 255, 255,  31,   0,   0,   0,   0},
  1380.      {255, 255, 255,  15,   0,   0,   0,   0},
  1381.      {255, 255, 255,   7,   0,   0,   0,   0},
  1382.      {255, 255, 255,   3,   0,   0,   0,   0},
  1383.      {255, 255, 255,   1,   0,   0,   0,   0},
  1384.      {255, 255, 255,   0,   0,   0,   0,   0},
  1385.      {255, 255, 127,   0,   0,   0,   0,   0},
  1386.      {255, 255,  63,   0,   0,   0,   0,   0},
  1387.      {255, 255,  31,   0,   0,   0,   0,   0},
  1388.      {255, 255,  15,   0,   0,   0,   0,   0},
  1389.      {255, 255,   7,   0,   0,   0,   0,   0},
  1390.      {255, 255,   3,   0,   0,   0,   0,   0},
  1391.      {255, 255,   1,   0,   0,   0,   0,   0},
  1392.      {255, 255,   0,   0,   0,   0,   0,   0},
  1393.      {255, 127,   0,   0,   0,   0,   0,   0},
  1394.      {255,  63,   0,   0,   0,   0,   0,   0},
  1395.      {255,  31,   0,   0,   0,   0,   0,   0},
  1396.      {255,  15,   0,   0,   0,   0,   0,   0},
  1397.      {255,   7,   0,   0,   0,   0,   0,   0},
  1398.      {255,   3,   0,   0,   0,   0,   0,   0},
  1399.      {255,   1,   0,   0,   0,   0,   0,   0},
  1400.      {255,   0,   0,   0,   0,   0,   0,   0},
  1401.      {127,   0,   0,   0,   0,   0,   0,   0},
  1402.      { 63,   0,   0,   0,   0,   0,   0,   0},
  1403.      { 31,   0,   0,   0,   0,   0,   0,   0},
  1404.      { 15,   0,   0,   0,   0,   0,   0,   0},
  1405.      {  7,   0,   0,   0,   0,   0,   0,   0},
  1406.      {  3,   0,   0,   0,   0,   0,   0,   0},
  1407.      {  1,   0,   0,   0,   0,   0,   0,   0}};
  1408.  
  1409.  
  1410.  
  1411.    /************************************************
  1412.    *
  1413.    *   print_graphics_image(...
  1414.    *
  1415.    ************************************************/
  1416.  
  1417. print_graphics_image(image1, image2, image_name,
  1418.                      il, ie, ll, le, image_colors,
  1419.                      invert, caption, show_hist,
  1420.                      color_transform)
  1421.    char  caption[], image_name[], color_transform[];
  1422.    int   image_colors, invert,
  1423.          il, ie, ll, le, show_hist;
  1424.    short image1[ROWS][COLS], image2[ROWS][COLS];
  1425. {
  1426.    char c[80],
  1427.         page[80];
  1428.  
  1429.    FILE *printer;
  1430.  
  1431.    int  i,
  1432.         j;
  1433.  
  1434.    unsigned long histogram[256], final_hist[256];
  1435.    printer = fopen("prn", "w");
  1436.  
  1437.  
  1438.       /**********************************************
  1439.       *
  1440.       *   Print a few blank lines on the page.
  1441.       *
  1442.       ***********************************************/
  1443.  
  1444.    strcpy(page, "                             \n");
  1445.    fputs(page, printer);
  1446.    fputs(page, printer);
  1447.  
  1448.  
  1449.       /***********************************************
  1450.       *
  1451.       *   Read in two image arrays.
  1452.       *
  1453.       ************************************************/
  1454.  
  1455.    printf("\nReading image");
  1456.    read_tiff_image(image_name, image1, il, ie, ll, le);
  1457.  
  1458.  
  1459.    printf("\nReading image");
  1460.    read_tiff_image(image_name, image2, 
  1461.                    il, ie+100, ll, le+100);
  1462.  
  1463.  
  1464.       /**********************************************
  1465.       *
  1466.       *   If show_hist is 1 OR do hist equalization
  1467.       *   then zero the histogram and
  1468.       *   calculate it for the two image arrays.
  1469.       *
  1470.       ***********************************************/
  1471.  
  1472.    if( (show_hist == 1)  ||
  1473.        (color_transform[0] == 'H')){
  1474.       zero_histogram(histogram);
  1475.       zero_histogram(final_hist);
  1476.       printf("\nDJET> Calculating histograms");
  1477.       calculate_histogram(image1, histogram);
  1478.       calculate_histogram(image2, histogram);
  1479.    }
  1480.  
  1481.         /*********************************************
  1482.         *
  1483.         *   Alter the images to 64 gray shades.
  1484.         *   Either do it with straight multiply
  1485.         *   and divide or use hist equalization.
  1486.         *
  1487.         *   If using hist equalization then you must
  1488.         *   also read and calculate the hist for
  1489.         *   the other two image arrays that will be
  1490.         *   printed.
  1491.         *
  1492.         **********************************************/
  1493.  
  1494.    if(color_transform[0] == 'S'){
  1495.    if(image_colors == 256){
  1496.       for(i=0; i<ROWS; i++){
  1497.          for(j=0; j<COLS; j++){
  1498.             image1[i][j] = image1[i][j]/4;
  1499.             image2[i][j] = image2[i][j]/4;
  1500.         }
  1501.       }
  1502.    }  /* ends if image_colors == 256 */
  1503.  
  1504.  
  1505.    if(image_colors == 16){
  1506.       for(i=0; i<ROWS; i++){
  1507.          for(j=0; j<COLS; j++){
  1508.             image1[i][j] = image1[i][j]*4;
  1509.             image2[i][j] = image2[i][j]*4;
  1510.         }
  1511.       }
  1512.    }  /* ends if image_colors == 16 */
  1513.    }  /* ends if color_transform == S */
  1514.  
  1515.    if(color_transform[0] == 'H'){
  1516.  
  1517.       printf("\nReading image");
  1518.       read_tiff_image(image_name, image1, 
  1519.                    il+100, ie, ll+100, le);
  1520.       printf("\nReading image");
  1521.       read_tiff_image(image_name, image2,
  1522.                    il+100, ie+100, ll+100, le+100);
  1523.       printf("\nDJET> Calculating histograms");
  1524.       calculate_histogram(image1, histogram);
  1525.       calculate_histogram(image2, histogram);
  1526.  
  1527.       printf("\nReading image");
  1528.       read_tiff_image(image_name, image1, 
  1529.                    il, ie, ll, le);
  1530.  
  1531.       printf("\nReading image");
  1532.       read_tiff_image(image_name, image2, 
  1533.                    il, ie+100, ll, le+100);
  1534.  
  1535.       printf("\nDJET> Equalizing histogram");
  1536.       perform_histogram_equalization(image1, histogram,
  1537.                                      64.0, 40000.0);
  1538.       printf("\nDJET> Equalizing histogram");
  1539.       perform_histogram_equalization(image2, histogram,
  1540.                                      64.0, 40000.0);
  1541.  
  1542.       printf("\nDJET> Calculating histograms");
  1543.       calculate_histogram(image1, final_hist);
  1544.       calculate_histogram(image2, final_hist);
  1545.  
  1546.  
  1547.    }  /* ends if color_transform == H */
  1548.  
  1549.  
  1550.  
  1551.       /*********************************************
  1552.       *
  1553.       *   If invert is set them invert the 
  1554.       *   transformed image arrays (they now 
  1555.       *   only have 64 shades of gray).
  1556.       *
  1557.       **********************************************/
  1558.  
  1559.    if(invert == 1){
  1560.       for(i=0; i<ROWS; i++){
  1561.          for(j=0; j<COLS; j++){
  1562.                image1[i][j] = 63 - image1[i][j];
  1563.                image2[i][j] = 63 - image2[i][j];
  1564.          }
  1565.       }
  1566.    }
  1567.  
  1568.  
  1569.  
  1570.         /********************************************
  1571.         *
  1572.         *   Now set the graphics mode on the printer
  1573.         *
  1574.         *********************************************/
  1575.  
  1576.    printf("\nBegin");
  1577.    end_graphics_mode(printer);
  1578.    select_300_dpi_resolution(printer);
  1579.    set_raster_width(printer);
  1580.    start_raster_graphics(printer);
  1581.    select_full_graphics_mode(printer);
  1582.  
  1583.         /*********************************************
  1584.         *
  1585.         *   Print the two arrays to make a 100x200 
  1586.         *   output. To do this you loop over 100 rows, 
  1587.         *   set the r buffer to the image values, set 
  1588.         *   the graphics, and print the row via 
  1589.         *   function print_original_200_row.
  1590.         *
  1591.         **********************************************/
  1592.  
  1593.    for(i=0; i<100; i++){
  1594.       for(j=0; j<100; j++){
  1595.          r[j]     = image1[i][j];
  1596.          r[j+100] = image2[i][j];
  1597.       }  /* ends loop over j */
  1598.  
  1599.       end_graphics_mode(printer);
  1600.       select_300_dpi_resolution(printer);
  1601.       set_raster_width(printer);
  1602.       start_raster_graphics(printer);
  1603.       select_full_graphics_mode(printer);
  1604.  
  1605.       print_original_200_row(printer, r);
  1606.  
  1607.       printf("\n\tPrinting row %d", i);
  1608.    }  /* ends loop over i */
  1609.  
  1610.            /* ends first half */
  1611.  
  1612.  
  1613.  
  1614.       /**********************************************
  1615.       *
  1616.       *   In order to print 200x200 repeat
  1617.       *   the above steps for 2 more 100x100 arrays
  1618.       *
  1619.       ***********************************************/
  1620.  
  1621.  
  1622.    printf("\nReading image");
  1623.    read_tiff_image(image_name, image1, 
  1624.                 il+100, ie, ll+100, le);
  1625.    printf("\nReading image");
  1626.    read_tiff_image(image_name, image2,
  1627.                 il+100, ie+100, ll+100, le+100);
  1628.  
  1629.  
  1630.         /*********************************************
  1631.         *
  1632.         *   Alter the images to 64 shades of gray.
  1633.         *
  1634.         *   Either do it with straight multiply
  1635.         *   and divide or use hist equalization.
  1636.         *
  1637.         **********************************************/
  1638.  
  1639.  
  1640.    if(color_transform[0] == 'S'){
  1641.    if(image_colors == 256){
  1642.       for(i=0; i<ROWS; i++){
  1643.          for(j=0; j<COLS; j++){
  1644.             image1[i][j] = image1[i][j]/4;
  1645.             image2[i][j] = image2[i][j]/4;
  1646.         }
  1647.       }
  1648.    }  /* ends if image_colors == 256 */
  1649.  
  1650.  
  1651.    if(image_colors == 16){
  1652.       for(i=0; i<ROWS; i++){
  1653.          for(j=0; j<COLS; j++){
  1654.             image1[i][j] = image1[i][j]*4;
  1655.             image2[i][j] = image2[i][j]*4;
  1656.         }
  1657.       }
  1658.    }  /* ends if image_colors == 16 */
  1659.    }  /* ends if color_transform == S */
  1660.  
  1661.  
  1662.  
  1663.    if(color_transform[0] == 'H'){
  1664.  
  1665.       printf("\nDJET> Equalizing histogram");
  1666.       perform_histogram_equalization(image1, histogram,
  1667.                                      64.0, 40000.0);
  1668.       printf("\nDJET> Equalizing histogram");
  1669.       perform_histogram_equalization(image2, histogram,
  1670.                                      64.0, 40000.0);
  1671.  
  1672.       printf("\nDJET> Calculating histograms");
  1673.       calculate_histogram(image1, final_hist);
  1674.       calculate_histogram(image2, final_hist);
  1675.  
  1676.    }  /* ends if color_transform == S */
  1677.  
  1678.  
  1679.  
  1680.  
  1681.       /************************************************
  1682.       *
  1683.       *   If invert is set them invert the transformed
  1684.       *   image arrays (they now only have 64 shades
  1685.       *   of gray).
  1686.       *
  1687.       *************************************************/
  1688.  
  1689.    if(invert == 1){
  1690.       for(i=0; i<ROWS; i++){
  1691.          for(j=0; j<COLS; j++){
  1692.                image1[i][j] = 63 - image1[i][j];
  1693.                image2[i][j] = 63 - image2[i][j];
  1694.          }
  1695.       }
  1696.    }
  1697.  
  1698.  
  1699.  
  1700.    printf("\nBegin");
  1701.    end_graphics_mode(printer);
  1702.    select_300_dpi_resolution(printer);
  1703.    set_raster_width(printer);
  1704.    start_raster_graphics(printer);
  1705.    select_full_graphics_mode(printer);
  1706.  
  1707.  
  1708.     /***********************************************
  1709.     *
  1710.     *   Print the two arrays to make a 100x200 output.
  1711.     *   To do this you loop over 100 rows, set the
  1712.     *   r buffer to the image values, set the
  1713.     *   graphics, and print the row via function
  1714.     *   print_original_200_row.
  1715.     *
  1716.     *************************************************/
  1717.  
  1718.    for(i=0; i<100; i++){
  1719.       for(j=0; j<100; j++){
  1720.          r[j]     = image1[i][j];
  1721.          r[j+100] = image2[i][j];
  1722.       }  /* ends loop over j */
  1723.  
  1724.       end_graphics_mode(printer);
  1725.       select_300_dpi_resolution(printer);
  1726.       set_raster_width(printer);
  1727.       start_raster_graphics(printer);
  1728.       select_full_graphics_mode(printer);
  1729.  
  1730.       print_original_200_row(printer, r);
  1731.  
  1732.       printf("\n\tPrinting row %d", i);
  1733.    }  /* ends loop over i */
  1734.  
  1735.  
  1736.       /**********************************************
  1737.       *
  1738.       *   If show_hist is 1 then calculate the 
  1739.       *   histogram for the two image arrays and 
  1740.       *   print the histogram.
  1741.       *
  1742.       ***********************************************/
  1743.  
  1744.    if(show_hist == 1){
  1745.       if(color_transform[0] == 'S'){
  1746.          calculate_histogram(image1, histogram);
  1747.          calculate_histogram(image2, histogram);
  1748.          print_hist_image(printer, histogram);
  1749.       }
  1750.       if(color_transform[0] == 'H'){
  1751.          print_hist_image(printer, final_hist);
  1752.       }
  1753.    }
  1754.  
  1755.         /*********************************************
  1756.         *
  1757.         *   Print a couple of blank lines then print
  1758.         *   the caption.
  1759.         *
  1760.         **********************************************/
  1761.  
  1762.    end_graphics_mode(printer);
  1763.    strcpy(page, "      \n");
  1764.    fputs(page, printer);
  1765.    fputs(page, printer);
  1766.  
  1767.    sprintf(page, "                      %s\n", caption);
  1768.    fputs(page, printer);
  1769.  
  1770.    fputc(FORMFEED, printer);
  1771.  
  1772.    fclose(printer);
  1773.  
  1774.    printf("\nEnd");
  1775.  
  1776. }  /* ends print_graphics_image */
  1777.  
  1778.  
  1779.  
  1780.    /******************************************
  1781.    *
  1782.    *   get_graphics_caption(...
  1783.    *
  1784.    ******************************************/
  1785.  
  1786. get_graphics_caption(caption)
  1787.    char caption[];
  1788. {
  1789.    printf("\nEnter the caption to be printed\n---");
  1790.    gets(caption);
  1791.  
  1792. }  /* ends get_graphics_caption */
  1793.  
  1794.  
  1795.  
  1796.  
  1797.    /************************************************
  1798.    *
  1799.    *   select_full_graphics_mode(...
  1800.    *
  1801.    ************************************************/
  1802.  
  1803. select_full_graphics_mode(printer)
  1804.  
  1805.    FILE *printer;
  1806. {
  1807.    fputc(ESCAPE, printer);
  1808.    fputc('*', printer);
  1809.    fputc('b', printer);
  1810.    fputc('0', printer);
  1811.    fputc('M', printer);
  1812.  
  1813. }
  1814.  
  1815.  
  1816.  
  1817.    /************************************************
  1818.    *
  1819.    *   set_horizontal_offset(...
  1820.    *
  1821.    ************************************************/
  1822.  
  1823. set_horizontal_offset(printer)
  1824.  
  1825.    FILE *printer;
  1826. {
  1827.    fputc(ESCAPE, printer);
  1828.    fputc('*', printer);
  1829.    fputc('b', printer);
  1830.    fputc('4', printer);
  1831.    fputc('9', printer);
  1832.    fputc('6', printer);
  1833.    fputc('X', printer);
  1834.  
  1835. }
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.    /************************************************
  1842.    *
  1843.    *   set_shorter_horizontal_offset(...
  1844.    *
  1845.    ************************************************/
  1846.  
  1847. set_shorter_horizontal_offset(printer)
  1848.  
  1849.    FILE *printer;
  1850. {
  1851.    fputc(ESCAPE, printer);
  1852.    fputc('*', printer);
  1853.    fputc('b', printer);
  1854.    fputc('4', printer);
  1855.    fputc('8', printer);
  1856.    fputc('0', printer);
  1857.    fputc('X', printer);
  1858.  
  1859. }
  1860.  
  1861.  
  1862.  
  1863.  
  1864.  
  1865.    /************************************************
  1866.    *
  1867.    *   end_graphics_mode(...
  1868.    *
  1869.    ************************************************/
  1870.  
  1871. end_graphics_mode(printer)
  1872.    FILE *printer;
  1873. {
  1874.    fputc(ESCAPE, printer);
  1875.    fputc('*', printer);
  1876.    fputc('r', printer);
  1877.    fputc('B', printer);
  1878. }
  1879.  
  1880.  
  1881.  
  1882.    /************************************************
  1883.    *
  1884.    *   set_raster_width(...
  1885.    *
  1886.    ************************************************/
  1887.  
  1888. set_raster_width(printer)
  1889.  
  1890.    FILE *printer;
  1891. {
  1892.    fputc(ESCAPE, printer);
  1893.    fputc('*', printer);
  1894.    fputc('r', printer);
  1895.    fputc('2', printer);
  1896.    fputc('2', printer);
  1897.    fputc('0', printer);
  1898.    fputc('0', printer);
  1899.    fputc('S', printer);
  1900.  
  1901. }
  1902.  
  1903.  
  1904.  
  1905.  
  1906.    /************************************************
  1907.    *
  1908.    *   start_raster_graphics(...
  1909.    *
  1910.    ************************************************/
  1911.  
  1912. start_raster_graphics(printer)
  1913.  
  1914.    FILE *printer;
  1915. {
  1916.    fputc(ESCAPE, printer);
  1917.    fputc('*', printer);
  1918.    fputc('r', printer);
  1919.    fputc('0', printer);
  1920.    fputc('A', printer);
  1921.  
  1922. }
  1923.  
  1924.  
  1925.  
  1926.  
  1927.    /************************************************
  1928.    *
  1929.    *   select_300_dpi_resolution(...
  1930.    *
  1931.    ************************************************/
  1932.  
  1933. select_300_dpi_resolution(printer)
  1934.  
  1935.    FILE *printer;
  1936. {
  1937.    fputc(ESCAPE, printer);
  1938.    fputc('*', printer);
  1939.    fputc('t', printer);
  1940.    fputc('3', printer);
  1941.    fputc('0', printer);
  1942.    fputc('0', printer);
  1943.    fputc('R', printer);
  1944.  
  1945. }
  1946.  
  1947.  
  1948.  
  1949.  
  1950.    /************************************************
  1951.    *
  1952.    *   print_bytes(...
  1953.    *
  1954.    ************************************************/
  1955.  
  1956. print_bytes(printer, buffer)
  1957.    FILE *printer;
  1958.    char buffer[];
  1959. {
  1960.    int        i;
  1961.  
  1962.    fputc(ESCAPE, printer);
  1963.    fputc('*', printer);
  1964.    fputc('b', printer);
  1965.    fputc('2', printer);
  1966.    fputc('0', printer);
  1967.    fputc('0', printer);
  1968.    fputc('W', printer);
  1969.  
  1970.  
  1971.    for(i=0; i<200; i++){
  1972.       fputc(buffer[i], printer);
  1973.    }
  1974. }  /* ends print_bytes */
  1975.  
  1976.  
  1977.  
  1978.  
  1979.    /**************************************************
  1980.    *
  1981.    *   print_original_200_row(...
  1982.    *
  1983.    ***************************************************/
  1984.  
  1985. print_original_200_row(printer, short_row)
  1986.    FILE  *printer;
  1987.    short short_row[200];
  1988. {
  1989.    char  row[8][200];
  1990.    char  c[200], response[80];
  1991.    int         i, j, k;
  1992.    short value;
  1993.    for(i=0; i<200; i++){
  1994.       value = short_row[i];
  1995.       if(value > 63) value = 63;
  1996.       if(value < 0)  value =  0;
  1997.  
  1998.       for(j=0; j<8; j++)
  1999.          row[j][i] = patterns[value][j];
  2000.  
  2001.    }  /* ends loop over i */
  2002.  
  2003.    for(i=0; i<8; i++){
  2004.       for(j=0; j<200; j++)
  2005.          c[j] = row[i][j];
  2006.       set_horizontal_offset(printer);
  2007.       print_bytes(printer, c);
  2008.    }  /* ends loop over i */
  2009.  
  2010. }  /* ends print_original_200_row */
  2011.  
  2012.  
  2013.  
  2014.  
  2015.  
  2016.  
  2017.    /***********************************
  2018.    *
  2019.    *   print_hist_image(...
  2020.    *
  2021.    ************************************/
  2022.  
  2023. print_hist_image(printer, hist)
  2024.    FILE *printer;
  2025.    unsigned long hist[];
  2026. {
  2027.    char   c, d;
  2028.    int          i, j, k;
  2029.    unsigned long limit, max;
  2030.  
  2031.    d = 0;
  2032.    c = 255;
  2033.  
  2034.       /********************************
  2035.       *
  2036.       *   First scale the histogram
  2037.       *
  2038.       *********************************/
  2039.  
  2040.    max = 0;
  2041.    for(i=0; i<256; i++)
  2042.       if(hist[i] > max) max = hist[i];
  2043.  
  2044.    if(max > 200){
  2045.       for(i=0; i<256; i++){
  2046.         hist[i] = (hist[i]*200)/max;
  2047.       }
  2048.    }
  2049.  
  2050.  
  2051.       /********************************
  2052.       *
  2053.       *   Second print it
  2054.       *
  2055.       *   Print a space between the image
  2056.       *   and the histogram.
  2057.       *
  2058.       *********************************/
  2059.  
  2060.  
  2061.    for(i=0; i<20; i++){
  2062.          end_graphics_mode(printer);
  2063.          select_300_dpi_resolution(printer);
  2064.          set_raster_width(printer);
  2065.          start_raster_graphics(printer);
  2066.          select_full_graphics_mode(printer);
  2067.          set_horizontal_offset(printer);
  2068.          fputc(ESCAPE, printer);
  2069.          fputc('*', printer);
  2070.          fputc('b', printer);
  2071.          fputc('2', printer);
  2072.          fputc('0', printer);
  2073.          fputc('0', printer);
  2074.          fputc('W', printer);
  2075.  
  2076.          for(j=0; j<200; j++)
  2077.             fputc(d, printer);
  2078.    }
  2079.  
  2080.  
  2081.    printf("\n\nHIST> Now printing the histogram");
  2082.    for(i=0; i<256; i++){
  2083.       printf("\n\tHIST> Histogram[%d]=%ld", 
  2084.             i, hist[i]);
  2085.  
  2086.             /* print the line 2 times */
  2087.       for(k=0; k<2; k++){
  2088.  
  2089.          end_graphics_mode(printer);
  2090.          select_300_dpi_resolution(printer);
  2091.          set_raster_width(printer);
  2092.          start_raster_graphics(printer);
  2093.          select_full_graphics_mode(printer);
  2094.  
  2095.  
  2096.             /***************************
  2097.             *
  2098.             *  Print grid marks every
  2099.             *  50 pixels.  Do this by
  2100.             *  setting a shorter margin
  2101.             *  then printing 2 marks then
  2102.             *  the data.
  2103.             *
  2104.             ****************************/
  2105.  
  2106.          if( (i ==   0) ||
  2107.              (i ==  50) ||
  2108.              (i == 100) ||
  2109.              (i == 150) ||
  2110.              (i == 200) ||
  2111.              (i == 255)){
  2112.  
  2113.             set_shorter_horizontal_offset(printer);
  2114.             fputc(ESCAPE, printer);
  2115.             fputc('*', printer);
  2116.             fputc('b', printer);
  2117.             fputc('2', printer);
  2118.             fputc('0', printer);
  2119.             fputc('2', printer);
  2120.             fputc('W', printer);
  2121.  
  2122.             fputc(c, printer);
  2123.             fputc(c, printer);
  2124.  
  2125.  
  2126.             if(hist[i] >= 200)
  2127.                hist[i] = 200;
  2128.  
  2129.             limit = 200 - hist[i];
  2130.  
  2131.             if(hist[i] == 0)
  2132.                fputc(c, printer);
  2133.  
  2134.             for(j=0; j<hist[i]; j++)
  2135.                fputc(c, printer);
  2136.  
  2137.             for(j=0; j<limit; j++)
  2138.               fputc(d, printer);
  2139.  
  2140.          }  /* ends print grid marks */
  2141.  
  2142.  
  2143.             /***************************
  2144.             *
  2145.             *  If you do not print
  2146.             *  grid marks, set the normal
  2147.             *  margin and then print the
  2148.             *  data.
  2149.             *
  2150.             ****************************/
  2151.  
  2152.          else{
  2153.             set_horizontal_offset(printer);
  2154.             /* this prints 200 bytes so print 200 */
  2155.             fputc(ESCAPE, printer);
  2156.             fputc('*', printer);
  2157.             fputc('b', printer);
  2158.             fputc('2', printer);
  2159.             fputc('0', printer);
  2160.             fputc('0', printer);
  2161.             fputc('W', printer);
  2162.  
  2163.             if(hist[i] >= 200)
  2164.                hist[i] = 200;
  2165.  
  2166.             limit = 200 - hist[i];
  2167.  
  2168.             if(hist[i] == 0)
  2169.                fputc(c, printer);
  2170.  
  2171.             for(j=0; j<hist[i]; j++)
  2172.                fputc(c, printer);
  2173.  
  2174.             for(j=0; j<limit; j++)
  2175.               fputc(d, printer);
  2176.  
  2177.          }  /* ends else no grid marks */
  2178.  
  2179.       }  /* ends loop over k */
  2180.  
  2181.    }  /* ends loop over i */
  2182.  
  2183. }  /* ends print_hist_image */
  2184.  
  2185.  
  2186.     /***********************************************
  2187.     *
  2188.     *       file d:\cips\scale.c
  2189.     *
  2190.     *       Functions: This file contains
  2191.     *          zoom_image_array
  2192.     *          shrink_image_array
  2193.     *          interpolate_pixel
  2194.     *          average_pixel
  2195.     *          median_pixel
  2196.     *          get_scaling_options
  2197.     *          blank_image_array
  2198.     *
  2199.     *       Purpose:
  2200.     *          These functions implement image array
  2201.     *          zooming (enlarging) and shrinking.
  2202.     *
  2203.     *       External Calls:
  2204.     *          wtiff.c - round_off_image_size
  2205.     *                    create_file_if_needed
  2206.     *                    write_array_into_tiff_image
  2207.     *          tiff.c - read_tiff_header
  2208.     *          rtiff.c - read_tiff_image
  2209.     *          numcvrt.c - get_integer
  2210.     *          filter.c - median_of
  2211.     *
  2212.     *       Modifications:
  2213.     *          8 April 1992 - created
  2214.     *
  2215.     *************************************************/
  2216.  
  2217.  
  2218.      /*******************************************
  2219.      *
  2220.      *   zoom_image_array(...
  2221.      *
  2222.      *   This function zooms in on an input
  2223.      *   image array.  It zooms by enlarging
  2224.      *   an input image array and writing the
  2225.      *   resulting image arrays to an output
  2226.      *   image file.  It can zoom or enlarge by
  2227.      *   a factor of 2 or 4.
  2228.      *
  2229.      *   You can zoom or enlarge an image array
  2230.      *   by using either the replication or
  2231.      *   interpolation methods.
  2232.      *
  2233.      *******************************************/
  2234.  
  2235.  
  2236. zoom_image_array(in_name, out_name, the_image, out_image,
  2237.           il, ie, ll, le, scale, method)
  2238.    char   in_name[], out_name[], method[];
  2239.    int    il, ie, ll, le, scale;
  2240.    short  the_image[ROWS][COLS],
  2241.           out_image[ROWS][COLS];
  2242. {
  2243.    int    A, B, a, b, count, factor, 
  2244.           i, j, length, width;
  2245.    struct tiff_header_struct image_header;
  2246.  
  2247.            /******************************************
  2248.            *
  2249.            *   Check the scale factor.  If it is not
  2250.            *   a valid factor (2 or 4), then set
  2251.            *   it to 2.
  2252.            *
  2253.            ******************************************/
  2254.  
  2255.    factor = scale;
  2256.    if(factor != 2 &&
  2257.       factor != 4) factor = 2;
  2258.  
  2259.    create_file_if_needed(in_name, out_name, out_image);
  2260.  
  2261.       /*******************************************
  2262.       *
  2263.       *   Let me try to explain the nested loops
  2264.       *   shown below.
  2265.       *
  2266.       *   We will enlarge the_image by the factor.
  2267.       *   Therefore, we want to divide the_image
  2268.       *   into parts of size ROWS/factor by
  2269.       *   COLS/factor.  We will loop through
  2270.       *   the_image parts ROWS/factor and COLS/factor
  2271.       *   using the loops over i and j.
  2272.       *
  2273.       *   We divided the_image into parts so we must
  2274.       *   include all of these parts.  That is why we
  2275.       *   do the loops over A and B.  There are
  2276.       *   factor*factor parts.
  2277.       *
  2278.       *   Finally, we do the loops over a and b.
  2279.       *   We must replicate every element in the_image
  2280.       *   factor*factor times and put these into
  2281.       *   out_image.  The a and b loops perform this
  2282.       *   task.
  2283.       *
  2284.       *   The equations inside the []'s for
  2285.       *   the_image and out_image are also confusing.
  2286.       *   If you work them out, you'll see that we
  2287.       *   are bouncing through the image arrays
  2288.       *   and fitting the pixels into the right
  2289.       *   places.
  2290.       *
  2291.       *   The final proof is that this works.
  2292.       *
  2293.       *   One final note:  the factor should divide
  2294.       *   evenly into ROWS.  For example, ROWS=100
  2295.       *   so using a factor of 8 is not good.
  2296.       *   100/8 = 12.5 and this leave you with
  2297.       *   an empty strip along the right and
  2298.       *   bottom edges of the out_image.
  2299.       *
  2300.       *******************************************/
  2301.  
  2302.            /*****************************************
  2303.            *
  2304.            *   Replication method
  2305.            *
  2306.            ******************************************/
  2307.  
  2308.    if(method[0] == 'r' || method[0] == 'R'){
  2309.       read_tiff_image(in_name, the_image, 
  2310.                       il, ie, ll, le);
  2311.       count = 1;
  2312.       for(A=0; A<factor; A++){
  2313.        for(B=0; B<factor; B++){
  2314.         for(i=0; i<ROWS/factor; i++){
  2315.          for(j=0; j<COLS/factor; j++){
  2316.           for(a=0; a<factor; a++){
  2317.            for(b=0; b<factor; b++){
  2318.              out_image[factor*i+a][factor*j+b] =
  2319.               the_image[i+A*ROWS/factor][j+B*COLS/factor];
  2320.            }  /* ends loop over b */
  2321.           }  /* ends loop over a */
  2322.          }  /* ends loop over j */
  2323.         }  /* ends loop over i */
  2324.         printf("\nzooming replication %3d of %3d",
  2325.                count++, factor*factor);
  2326.         write_array_into_tiff_image(out_name, out_image,
  2327.             1+A*ROWS, 1+B*COLS, 101+A*ROWS, 101+B*COLS);
  2328.        }  /* ends loop over B */
  2329.       }  /* ends loop over A */
  2330.    }  /* ends replication method */
  2331.  
  2332.            /***************************
  2333.            *
  2334.            *   Interpolation method
  2335.            *
  2336.            ****************************/
  2337.  
  2338.    if(method[0] == 'i' || method[0] == 'I'){
  2339.       read_tiff_image(in_name, the_image,
  2340.                       il, ie, ll, le);
  2341.       count = 1;
  2342.       for(A=0; A<factor; A++){
  2343.          for(B=0; B<factor; B++){
  2344.           for(i=0; i<ROWS/factor; i++){
  2345.            for(j=0; j<COLS/factor; j++){
  2346.             for(a=0; a<factor; a++){
  2347.              for(b=0; b<factor; b++){
  2348.                 out_image[factor*i+a][factor*j+b] =
  2349.                   interpolate_pixel(the_image, A, B,
  2350.                               i, j, a, b, factor);
  2351.              }  /* ends loop over b */
  2352.             }  /* ends loop over a */
  2353.            }  /* ends loop over j */
  2354.           }  /* ends loop over i */
  2355.        printf("\nzooming interpolation %3d of %3d",
  2356.                      count++, factor*factor);
  2357.        write_array_into_tiff_image(out_name, out_image,
  2358.                  1+A*ROWS, 1+B*COLS,
  2359.                  101+A*ROWS, 101+B*COLS);
  2360.      }  /* ends loop over B */
  2361.     }  /* ends loop over A */
  2362.    }  /* ends interpolation method */
  2363.  
  2364.  
  2365. }  /* ends zoom_image_array */
  2366.  
  2367.  
  2368.  
  2369.  
  2370.  
  2371.     /***********************************************
  2372.     *
  2373.     *    interpolate_pixel(...
  2374.     *
  2375.     *    This function interpolates between pixel
  2376.     *    values and returns the interlopated value.
  2377.     *
  2378.     ***********************************************/
  2379.  
  2380. interpolate_pixel(the_image, A, B, i, j, a, b, factor)
  2381.    int   A, B, a, b, factor, i, j;
  2382.    short the_image[ROWS][COLS];
  2383. {
  2384.    int   num, x = 0, y = 0;
  2385.    short diff, result;
  2386.  
  2387.    if(a > 0) y = 1;
  2388.    if(b > 0) x = 1;
  2389.    diff = 
  2390.       the_image[y+i+A*ROWS/factor][x+j+B*COLS/factor] -
  2391.       the_image[i+A*ROWS/factor][j+B*COLS/factor];
  2392.  
  2393.           /******************************************
  2394.           *
  2395.           * If you are at the edge of the input image
  2396.           * array, then you cannot interpolate to the
  2397.           * next point because there is no next point.
  2398.           * Therefore, set the diff to 0.
  2399.           *
  2400.           *******************************************/
  2401.  
  2402.    if((y+i+A*ROWS/factor) >= ROWS) diff = 0;
  2403.    if((x+j+B*COLS/factor) >= COLS) diff = 0;
  2404.  
  2405.    num = a+b;
  2406.    if(num > factor) num = factor;
  2407.    result = the_image[i+A*ROWS/factor][j+B*COLS/factor] +
  2408.             num*diff/factor;
  2409.    return(result);
  2410. }  /* ends interpolate_pixel */
  2411.  
  2412.  
  2413.  
  2414.  
  2415.  
  2416.      /*******************************************
  2417.      *
  2418.      *   shrink_image_array(...
  2419.      *
  2420.      *   This function shrinks a part of an
  2421.      *   image.  It takes a part of an input
  2422.      *   image (described by il1, ie1, ll1, le1)
  2423.      *   shrinks a 200x200 or 400x400 area down
  2424.      *   to a 100x100 array, and writes this result
  2425.      *   to an output file.  The location in the
  2426.      *   output file is described by il2, ie2,
  2427.      *   ll2, le2.
  2428.      *
  2429.      *   You can shrink the input image area
  2430.      *   by using either the averaging, median,
  2431.      *   or corner method.
  2432.      *
  2433.      *******************************************/
  2434.  
  2435. shrink_image_array(in_name, out_name, 
  2436.           the_image, out_image,
  2437.           il1, ie1, ll1, le1, il2, ie2, ll2, le2,
  2438.           scale, method)
  2439.    char   in_name[], out_name[], method[];
  2440.    int    il1, ie1, ll1, le1,
  2441.           il2, ie2, ll2, le2, scale;
  2442.    short  the_image[ROWS][COLS],
  2443.           out_image[ROWS][COLS];
  2444. {
  2445.    int    A, B, a, b, count, factor, 
  2446.           i, j, length, width;
  2447.    struct tiff_header_struct image_header;
  2448.  
  2449.            /******************************************
  2450.            *
  2451.            *   Check the scale factor.  If it is not
  2452.            *   a valid factor (2 or 4), then set
  2453.            *   it to 2.
  2454.            *
  2455.            ******************************************/
  2456.  
  2457.    factor = scale;
  2458.    if(factor != 2 &&
  2459.       factor != 4) factor = 2;
  2460.  
  2461.    create_file_if_needed(in_name, out_name, out_image);
  2462.  
  2463.    read_tiff_header(in_name, &image_header);
  2464.  
  2465.       /**********************************************
  2466.       *
  2467.       *   Let me try to explain the nested loops
  2468.       *   shown below.
  2469.       *
  2470.       *   We will shrink the_image by the factor.
  2471.       *   Therefore, we want to read in factor*factor
  2472.       *   image arrays and produce one ROWS by COLS
  2473.       *   array for writing to disk.
  2474.       *   That is why we loop over A and B.
  2475.       *
  2476.       *   We want to set every pixel in the out_image
  2477.       *   array so we loop over i and j.
  2478.       *
  2479.       *   The equations inside the out_image []'s
  2480.       *   look a little strange.  What we are doing is
  2481.       *   setting every element and moving over every
  2482.       *   time through the loops over A and B.  
  2483.       *   The first loop is for i=0,49 then i=50,99 
  2484.       *   for a factor=2 and ROWS=100.
  2485.       *
  2486.       *   The final proof is that this works.
  2487.       *
  2488.       *   One final note:  the factor should divide
  2489.       *   evenly into ROWS.  For example, ROWS=100
  2490.       *   so using a factor of 8 is not good.
  2491.       *   100/8 = 12.5 and this leave you with
  2492.       *   an empty strip along the right and
  2493.       *   bottom edges of the out_image.
  2494.       *
  2495.       ************************************************/
  2496.  
  2497.            /********************************
  2498.            *
  2499.            *   Corner method
  2500.            *
  2501.            *********************************/
  2502.  
  2503.    if(method[0] == 'c' || method[0] == 'C'){
  2504.       count = 1;
  2505.       for(A=0; A<factor; A++){
  2506.        for(B=0; B<factor; B++){
  2507.         printf("\n shrinking by corner %3d of %3d",
  2508.                      count++, factor*factor);
  2509.         if(image_header.image_length < ll1+A*ROWS   ||
  2510.            image_header.image_width  < le1+B*COLS)
  2511.            blank_image_array(the_image);
  2512.         else
  2513.            read_tiff_image(in_name, the_image,
  2514.                            il1+A*ROWS, ie1+B*COLS,
  2515.                            ll1+A*ROWS, le1+B*COLS);
  2516.         for(i=0; i<ROWS/factor; i++){
  2517.          for(j=0; j<COLS/factor; j++){
  2518.             out_image[i+A*ROWS/factor][j+B*COLS/factor] =
  2519.                      the_image[factor*i][factor*j];
  2520.          }  /* ends loop over j */
  2521.         }  /* ends loop over i */
  2522.        }  /* ends loop over B */
  2523.       }  /* ends loop over A */
  2524.       write_array_into_tiff_image(out_name, out_image,
  2525.                                   il2, ie2, ll2, le2);
  2526.    } /* ends corner method */
  2527.  
  2528.            /******************************
  2529.            *
  2530.            *   Average Method
  2531.            *
  2532.            ******************************/
  2533.  
  2534.    if(method[0] == 'a' || method[0] == 'A'){
  2535.       count = 1;
  2536.       for(A=0; A<factor; A++){
  2537.        for(B=0; B<factor; B++){
  2538.         printf("\n shrinking by average %3d of %3d",
  2539.                      count++, factor*factor);
  2540.         if(image_header.image_length < ll1+A*ROWS   ||
  2541.            image_header.image_width  < le1+B*COLS)
  2542.            blank_image_array(the_image);
  2543.         else
  2544.            read_tiff_image(in_name, the_image,
  2545.                           il1+A*ROWS, ie1+B*COLS,
  2546.                           ll1+A*ROWS, le1+B*COLS);
  2547.         for(i=0; i<ROWS/factor; i++){
  2548.          for(j=0; j<COLS/factor; j++){
  2549.           out_image[i+A*ROWS/factor][j+B*COLS/factor] =
  2550.                 average_pixel(the_image, factor, i, j);
  2551.          }  /* ends loop over j */
  2552.         }  /* ends loop over i */
  2553.        }  /* ends loop over B */
  2554.       }  /* ends loop over A */
  2555.       write_array_into_tiff_image(out_name, out_image,
  2556.                                   il2, ie2, ll2, le2);
  2557.    } /* ends average method */
  2558.  
  2559.            /************************
  2560.            *
  2561.            *   Median Method
  2562.            *
  2563.            *************************/
  2564.  
  2565.    if(method[0] == 'm' || method[0] == 'M'){
  2566.       count = 1;
  2567.       for(A=0; A<factor; A++){
  2568.        for(B=0; B<factor; B++){
  2569.         printf("\n shrinking by median %3d of %3d",
  2570.                      count++, factor*factor);
  2571.         if(image_header.image_length < ll1+A*ROWS   ||
  2572.            image_header.image_width  < le1+B*COLS)
  2573.            blank_image_array(the_image);
  2574.         else
  2575.            read_tiff_image(in_name, the_image,
  2576.                            il1+A*ROWS, ie1+B*COLS,
  2577.                            ll1+A*ROWS, le1+B*COLS);
  2578.         for(i=0; i<ROWS/factor; i++){
  2579.          for(j=0; j<COLS/factor; j++){
  2580.           out_image[i+A*ROWS/factor][j+B*COLS/factor] =
  2581.                 median_pixel(the_image, factor, i, j);
  2582.          }  /* ends loop over j */
  2583.         }  /* ends loop over i */
  2584.        }  /* ends loop over B */
  2585.       }  /* ends loop over A */
  2586.       write_array_into_tiff_image(out_name, out_image,
  2587.                                   il2, ie2, ll2, le2);
  2588.    } /* ends median method */
  2589.  
  2590. }  /* ends shrink_image_array */
  2591.  
  2592.  
  2593.  
  2594.  
  2595.  
  2596.     /***********************************************
  2597.     *
  2598.     *   average_pixel(...
  2599.     *
  2600.     *   This function calculates the average
  2601.     *   pixel value of a factor x factor array
  2602.     *   of pixels inside the the_image array.
  2603.     *   The coordinates i and j point to the upper
  2604.     *   left hand corner of the small array.
  2605.     *
  2606.     ***********************************************/
  2607.  
  2608. average_pixel(the_image, factor, i, j)
  2609.    int   factor, i, j;
  2610.    short the_image[ROWS][COLS];
  2611. {
  2612.    int a, b, result = 0;
  2613.  
  2614.    for(a=0; a<factor; a++)
  2615.       for(b=0; b<factor; b++)
  2616.          result = result + 
  2617.                   the_image[factor*i+a][factor*j+a];
  2618.    result = result/(factor*factor);
  2619.  
  2620.    return(result);
  2621. }  /* ends average_pixel */
  2622.  
  2623.  
  2624.  
  2625.  
  2626.  
  2627.     /***********************************************
  2628.     *
  2629.     *   median_pixel(...
  2630.     *
  2631.     *   This function calculates the median
  2632.     *   pixel value of a factor x factor array
  2633.     *   of pixels inside the the_image array.
  2634.     *   The coordinates i and j point to the upper
  2635.     *   left hand corner of the small array.
  2636.     *
  2637.     ***********************************************/
  2638.  
  2639. median_pixel(the_image, factor, i, j)
  2640.    int   factor, i, j;
  2641.    short the_image[ROWS][COLS];
  2642. {
  2643.    int   a, b, count, ff, result = 0;
  2644.    short *elements;
  2645.  
  2646.    ff       = factor*factor;
  2647.    elements = (short *) malloc(ff * sizeof(short));
  2648.  
  2649.      count = 0;
  2650.    for(a=0; a<factor; a++){
  2651.          for(b=0; b<factor; b++){
  2652.             elements[count] = 
  2653.                the_image[factor*i+a][factor*j+b];
  2654.               count++;
  2655.         }
  2656.      }
  2657.  
  2658.    result = median_of(elements, &ff);
  2659.    free(elements);
  2660.    return(result);
  2661.  
  2662. }  /* ends median_pixel */
  2663.  
  2664.  
  2665.  
  2666.  
  2667.  
  2668.     /***********************************************
  2669.     *
  2670.     *    get_scaling_options(...
  2671.     *
  2672.     *    This function queries the user for the
  2673.     *    parameters needed to perform scaling.
  2674.     *
  2675.     ***********************************************/
  2676.  
  2677. get_scaling_options(zoom_shrink, scale, method)
  2678.    int *scale;
  2679.    char method[], zoom_shrink[];
  2680. {
  2681.    int not_finished = 1, response;
  2682.  
  2683.    while(not_finished){
  2684.       printf("\n\t1. Zoom or Shrink is - %s", 
  2685.              zoom_shrink);
  2686.       printf("\n\t2. Scale factor is %d", *scale);
  2687.       printf("\n\t3. Scaling Method is - %s", method);
  2688.       printf(
  2689.       "\n\t     Replication or Interpolation for Zooming"
  2690.       "\n\t     Averaging Median or Corner for Shrinking");
  2691.       printf("\n\n\tEnter choice (0 = no change) _\b");
  2692.       get_integer(&response);
  2693.  
  2694.       if(response == 0){
  2695.         not_finished = 0;
  2696.       }
  2697.  
  2698.       if(response == 1){
  2699.          printf("\nEnter Zoom or Shrink (z or s) __\b");
  2700.          gets(zoom_shrink);
  2701.       }
  2702.  
  2703.       if(response == 2){
  2704.          printf("\nEnter Scale Factor (2 or 4) __\b");
  2705.          get_integer(scale);
  2706.       }
  2707.  
  2708.       if(response == 3){
  2709.          printf("\nEnter Scaling Method: "
  2710.             "Replication or Interpolation for Zooming"
  2711.             "\n                      "
  2712.             "Averaging Median or Corner for Shrinking"
  2713.             "\n\t__\b");
  2714.          gets(method);
  2715.       }
  2716.  
  2717.    }  /* ends while not_finished */
  2718. }  /* ends get_scaling_options */
  2719.  
  2720.  
  2721.  
  2722.  
  2723.  
  2724.     /***********************************************
  2725.     *
  2726.     *   blank_image_array(...
  2727.     *
  2728.     *   This function blanks out an image array
  2729.     *   by filling it with zeros.
  2730.     *
  2731.     ***********************************************/
  2732.  
  2733. blank_image_array(image)
  2734.    short image[ROWS][COLS];
  2735. {
  2736.    int i, j;
  2737.    for(i=0; i<ROWS; i++)
  2738.       for(j=0; j<COLS; j++)
  2739.          image[i][j] = 0;
  2740. }  /* ends blank_image_array */
  2741.